<template>
  <div class="terminal-container">
    <div class="terminal-header">
      <div class="connection-info">
        <el-tag size="small" :type="isConnected ? 'success' : 'danger'">
          {{ isConnected ? '已连接' : '未连接' }}
        </el-tag>
        <span class="host-info" v-if="host">{{ user }}@{{ host }}</span>
      </div>
      <div class="actions">
        <el-button-group>
          <el-button size="small" type="primary" @click="connect" :disabled="isConnected">
            <el-icon><Link /></el-icon>
            连接
          </el-button>
          <el-button size="small" type="danger" @click="disconnect" :disabled="!isConnected">
            <el-icon><Close /></el-icon>
            断开
          </el-button>
        </el-button-group>
      </div>
    </div>

    <div ref="terminalEl" class="terminal-content"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import { WebLinksAddon } from 'xterm-addon-web-links'
import 'xterm/css/xterm.css'
import { ElMessage } from 'element-plus'
import { Link, Close } from '@element-plus/icons-vue'

const props = defineProps<{
  host: string
  user: string
  password: string
}>()

const terminalEl = ref<HTMLElement>()
const isConnected = ref(false)
let terminal: Terminal | null = null
let websocket: WebSocket | null = null
let fitAddon: FitAddon | null = null

// 初始化终端
const initTerminal = () => {
  if (!terminalEl.value) return

  terminal = new Terminal({
    cursorBlink: true,
    fontSize: 14,
    fontFamily: 'Menlo, Monaco, "Courier New", monospace',
    theme: {
      background: '#1e1e1e',
      foreground: '#ffffff',
    },
  })

  // 添加插件
  fitAddon = new FitAddon()
  terminal.loadAddon(fitAddon)
  terminal.loadAddon(new WebLinksAddon())

  // 打开终端
  terminal.open(terminalEl.value)
  fitAddon.fit()

  // 监听终端输入
  terminal.onData((data) => {
    if (websocket && websocket.readyState === WebSocket.OPEN) {
      websocket.send(data)
    }
  })
}

// 连接WebSocket
const connect = () => {
  if (!terminal) return

  const wsUrl = `ws://127.0.0.1:8080/ws/shell?host=${props.host}&user=${props.user}&password=${props.password}`
  websocket = new WebSocket(wsUrl)

  websocket.onopen = () => {
    isConnected.value = true
    ElMessage.success('终端连接成功')
  }

  websocket.onmessage = (event) => {
    if (terminal) {
      terminal.write(event.data)
    }
  }

  websocket.onerror = (error) => {
    console.error('WebSocket error:', error)
    ElMessage.error('终端连接失败')
    disconnect()
  }

  websocket.onclose = () => {
    isConnected.value = false
    ElMessage.warning('终端连接已断开')
  }
}

// 断开连接
const disconnect = () => {
  if (websocket) {
    websocket.close()
    websocket = null
  }
  if (terminal) {
    terminal.clear()
  }
  isConnected.value = false
}

// 窗口大小改变时调整终端大小
const handleResize = () => {
  if (fitAddon) {
    fitAddon.fit()
  }
}

onMounted(() => {
  initTerminal()
  window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
  disconnect()
  if (terminal) {
    terminal.dispose()
  }
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped lang="scss">
.terminal-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #1e1e1e;
  border-radius: 4px;
  overflow: hidden;

  .terminal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 16px;
    background-color: #252526;
    border-bottom: 1px solid #333;

    .connection-info {
      display: flex;
      align-items: center;
      gap: 12px;

      .host-info {
        color: #fff;
        font-family: monospace;
      }
    }

    .actions {
      .el-button {
        .el-icon {
          margin-right: 4px;
        }
      }
    }
  }

  .terminal-content {
    flex: 1;
    padding: 12px;

    :deep(.xterm) {
      height: 100%;

      .xterm-viewport {
        background-color: #1e1e1e !important;
      }
    }
  }
}
</style>
